package com.zmc.member.infrastructure.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zmc.common.domain.vo.member.MemberInfo;
import com.zmc.common.utils.token.AuthTokenService;
import com.zmc.member.infrastructure.constant.MemberConstants;
import com.zmc.member.infrastructure.bean.vo.ReceiveAddressVo;
import com.zmc.member.infrastructure.entity.AreaInfoEntity;
import com.zmc.member.infrastructure.service.AreaInfoService;
import com.zmc.member.exception.AddressMaxCountException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.zmc.member.infrastructure.dao.MemberReceiveAddressDao;
import com.zmc.member.infrastructure.entity.MemberReceiveAddressEntity;
import com.zmc.member.infrastructure.service.MemberReceiveAddressService;
import org.springframework.transaction.annotation.Transactional;


/**
 * @author zmc
 */
@Service("memberReceiveAddressService")
public class MemberReceiveAddressServiceImpl extends ServiceImpl<MemberReceiveAddressDao, MemberReceiveAddressEntity> implements MemberReceiveAddressService {

    @Autowired
    private AuthTokenService authTokenService;

    @Autowired
    private AreaInfoService areaInfoService;

    @Value("${receive.address.maxCount}")
    private Integer addressMaxCount;

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void saveReceiveAddress(ReceiveAddressVo vo) {
        LambdaQueryWrapper<MemberReceiveAddressEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MemberReceiveAddressEntity::getMemberId, authTokenService.getMemberInfo().getMemberId());
        long count = count(wrapper);
        if (count >= addressMaxCount) {
            throw new AddressMaxCountException();
        }
        check(vo);
        MemberReceiveAddressEntity entity = getEntity(vo);
        save(entity);
    }


    @Override
    public List<ReceiveAddressVo> listReceiveAddress() {
        LambdaQueryWrapper<MemberReceiveAddressEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MemberReceiveAddressEntity::getMemberId, authTokenService.getMemberInfo().getMemberId());
        return getVoList(list(wrapper));
    }

    @Override
    @Transactional
    public void updateReceiveAddress(ReceiveAddressVo receiveAddressVo) {
        check(receiveAddressVo);
        MemberReceiveAddressEntity entity = getEntity(receiveAddressVo);
        entity.setId(receiveAddressVo.getId());
        updateById(entity);
    }

    private MemberReceiveAddressEntity getEntity(ReceiveAddressVo vo) {
        MemberInfo memberInfo = authTokenService.getMemberInfo();
        MemberReceiveAddressEntity entity = new MemberReceiveAddressEntity();
        entity.setMemberId(memberInfo.getMemberId());
        entity.setName(vo.getReceiver());
        entity.setPhone(vo.getContact());
        List<AreaInfoEntity> areas = areaInfoService.getListByCodes(vo.getAddress());
        entity.setProvince(areas.get(0).getName());
        entity.setProvinceCode(areas.get(0).getCode());
        entity.setCity(areas.get(1).getName());
        entity.setCityCode(areas.get(1).getCode());
        entity.setRegion(areas.get(2).getName());
        entity.setRegionCode(areas.get(2).getCode());
        entity.setPostCode(areas.get(2).getCode());
        entity.setDetailAddress(vo.getDetailAddress());
        entity.setDefaultStatus(vo.getIsDefault());
        return entity;
    }

    private List<ReceiveAddressVo> getVoList(List<MemberReceiveAddressEntity> list) {
        List<ReceiveAddressVo> voList = new ArrayList<>();
        for (MemberReceiveAddressEntity entity : list) {
            ReceiveAddressVo vo = new ReceiveAddressVo();
            vo.setId(entity.getId());
            vo.setReceiver(entity.getName());
            vo.setContact(entity.getPhone());
            vo.setDetailAddress(entity.getDetailAddress());
            vo.setIsDefault(entity.getDefaultStatus());
            vo.setPostCode(entity.getPostCode());
            List<String> codes = new ArrayList<>();
            codes.add(entity.getProvinceCode());
            codes.add(entity.getCityCode());
            codes.add(entity.getRegionCode());
            vo.setAddress(codes);
            voList.add(vo);
        }
        return voList;
    }

    public MemberReceiveAddressEntity getOneDefaultReceive() {
        LambdaQueryWrapper<MemberReceiveAddressEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MemberReceiveAddressEntity::getMemberId, authTokenService.getMemberInfo().getMemberId())
                .eq(MemberReceiveAddressEntity::getDefaultStatus, MemberConstants.RECEIVE_ADDRESS_DEFAULT)
                .orderByAsc(MemberReceiveAddressEntity::getCreateTime);
        return getOne(wrapper);
    }

    /**
     * 检查默认地址
     */
    @Transactional
    public void check(ReceiveAddressVo vo) {
        //若当前地址为默认收货地址，则检查地址列表是否有设置默认选中项，若有，则更改状态为不是默认状态
        if (MemberConstants.RECEIVE_ADDRESS_DEFAULT == vo.getIsDefault()) {
            MemberReceiveAddressEntity receive = getOneDefaultReceive();
            if (receive != null) {
                receive.setDefaultStatus(MemberConstants.RECEIVE_ADDRESS_NOT_DEFAULT);
                updateById(receive);
            }
        }
    }
}